package com.shenhaofeng.app.utils.io;

import com.shenhaofeng.app.log.AppLog;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;


/**
 * 文件处理工具类
 * Created by Administrator on 2016/8/1.
 */
public class FileUtil {

    private static final String TAG = "FileUtil";


    /**
     * 生成一个文件
     *
     * @param file 生成的文件对象
     * @return 文件是否创建成功
     */
    public static boolean obtainFile(File file) {
        try {
            if (file.exists() && file.isFile()) {
                return true;
            } else if (!file.exists()) {
                File parent = file.getParentFile();
                if (parent == null) {
                    return file.createNewFile();
                } else {
                    return obtainDir(parent) && file.createNewFile();
                }
            } else {
                return false;
            }
        } catch (IOException e) {
            return false;
        }
    }


    /**
     * 保证文件的根目录被创建
     *
     * @param file 需要的文件路径
     * @return 父路径是否存在或以创建
     */
    public static boolean obtainFileParent(File file) {
        if (file.exists() && file.isFile()) {
            return true;
        } else if (file.exists() && file.isDirectory()) {//如果存在但是file是目录路径
            return false;
        } else {
            File parent = file.getParentFile();
            if (parent == null) {
                return true;
            } else {
                return obtainDir(parent);
            }
        }
    }


    /**
     * 创建目录
     *
     * @param dir
     * @return
     */
    public static boolean obtainDir(File dir) {
        if (dir.exists() && dir.isDirectory()) {
            return true;
        } else if (!dir.exists()) {
            return dir.mkdirs();
        } else {
            return false;
        }
    }


    /**
     * 清空一个文件夹
     *
     * @param dir
     * @return
     */
    public static long cleanDir(File dir) {
        File[] files = dir.listFiles();
        if (files == null) {
            return 0;
        } else {
            return _cleanDir(dir);
        }
    }


    private static long _cleanDir(File dir) {
        File[] files = dir.listFiles();
        if (files == null) {
            return 0;
        }
        long deletedCount = 0;
        for (File file : files) {
            if (file.isFile() && file.delete()) {
                deletedCount++;
            } else {
                deletedCount += _cleanDir(file);
            }
        }
        return deletedCount;
    }


    /**
     * 将可序列化的对象写入文件中
     *
     * @param file 写入的文件,请确保文件以创建或可被创建
     * @param data 被写入的序列化数据
     * @return 写入结果
     */
    public static boolean writeSerializableToFile(File file, Serializable data) {
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);
            outputStream.writeObject(data);
            outputStream.flush();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 写入文本
     *
     * @param file
     * @param string
     * @return
     */
    public static boolean writeTextToFile(File file, String string) {
        if (string == null) {
            return true;
        }
        try {
            FileWriter fileWriter = new FileWriter(file);
            fileWriter.write(string);
            fileWriter.flush();
            return true;
        } catch (IOException e) {
            AppLog.w(TAG, e.getMessage());
            return false;
        }
    }


    /**
     * 写入数字
     *
     * @param file
     * @param number
     * @return
     */
    public static boolean writeNumberToFile(File file, Number number) {
        return writeTextToFile(file, number == null ? "0" : number.toString());
    }


    /**
     * 写入布尔值
     *
     * @param file
     * @param value
     * @return
     */
    public static boolean writeBooleanrToFile(File file, boolean value) {
        return writeTextToFile(file, Boolean.toString(value));
    }


    /**
     * 读取文件中的序列化数据
     *
     * @param file        文件,如果文件不存在,将直接返回默认值
     * @param defaultData
     * @return
     */
    public static Serializable readSerializable(File file, Serializable defaultData) {
        if (file == null || !file.exists() || !file.isFile()) {
            return defaultData;
        }
        ObjectInputStream objectInputStream;
        try {
            objectInputStream = new ObjectInputStream(new FileInputStream(file));
            Object data = objectInputStream.readObject();
            if (data == null) {
                return defaultData;
            } else if (Serializable.class.isInstance(data)) {
                return Serializable.class.cast(data);
            } else {
                return defaultData;
            }
        } catch (IOException | ClassNotFoundException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultData;
        }
    }


    /**
     * 读取文件中的序列化数据
     *
     * @param file
     * @return 如果无法读取或数据不存在可能会返回null
     */
    public static Serializable readSerializable(File file) {
        return readSerializable(file, null);
    }


    /**
     * 将文本读取出来
     *
     * @param file
     * @return 文本信息
     */
    public static String readText(File file, String defaultData) {
        BufferedReader read = null;
        try {
            if (file == null) {
                return defaultData;
            }
            FileReader fileReader = null;
            fileReader = new FileReader(file);
            read = new BufferedReader(fileReader);
            read.close();
            StringBuffer buffer = new StringBuffer();
            while (read.ready()) {
                buffer.append(read.readLine());
            }
            return buffer.toString();
        } catch (IOException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultData;
        } finally {
            try {
                if (read != null) {
                    read.close();
                }
            } catch (IOException e) {
                AppLog.w(TAG, e.getMessage());
            }
        }

    }


    public static byte readByte(File file, byte defaultValue) {
        String value = readText(file, String.valueOf(defaultValue));
        try {
            return Byte.parseByte(value);
        } catch (NumberFormatException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultValue;
        }
    }


    public static byte readByte(File file) {
        return readByte(file, (byte) 0);
    }


    public static short readShort(File file, short defaultValue) {
        String value = readText(file, String.valueOf(defaultValue));
        try {
            return Short.parseShort(value);
        } catch (NumberFormatException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultValue;
        }
    }


    public static short readShort(File file) {
        return readShort(file, (short) 0);
    }


    public static int readInt(File file, int defaultValue) {
        String value = readText(file, String.valueOf(defaultValue));
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultValue;
        }
    }


    public static int readInt(File file) {
        return readInt(file, 0);
    }


    public static long readLong(File file, long defaultValue) {
        String value = readText(file, String.valueOf(defaultValue));
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultValue;
        }
    }


    public static long readLong(File file) {
        return readLong(file, 0L);
    }


    public static float readFloat(File file, float defaultValue) {
        String value = readText(file, String.valueOf(defaultValue));
        try {
            return Float.parseFloat(value);
        } catch (NumberFormatException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultValue;
        }
    }


    public static float readFloat(File file) {
        return readFloat(file, 0F);
    }


    public static double readDouble(File file, double defaultValue) {
        String value = readText(file, String.valueOf(defaultValue));
        try {
            return Double.parseDouble(value);
        } catch (NumberFormatException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultValue;
        }
    }


    public static double readDouble(File file) {
        return readDouble(file, 0D);
    }


    public static boolean readBoolean(File file, boolean defaultValue) {
        String value = readText(file, String.valueOf(defaultValue));
        try {
            return Boolean.parseBoolean(value);
        } catch (NumberFormatException e) {
            AppLog.w(TAG, e.getMessage());
            return defaultValue;
        }
    }


    public static boolean readBoolean(File file) {
        return readBoolean(file, false);
    }

}
